<template>
  <div>
    <!-- 面包屑-->
    <el-breadcrumb separator-class='el-icon-arrow-right'>
      <el-breadcrumb-item :to="{ path: '/goods' }">商品列表</el-breadcrumb-item>
      <el-breadcrumb-item>添加商品</el-breadcrumb-item>
    </el-breadcrumb>
    <el-divider></el-divider>
    <el-card>
      <el-row>
        <el-alert
          title='消息提示的文案' show-icon type='warning' effect='light' :closable='false' center>
        </el-alert>
      </el-row>
      <el-row class='row-step'>
        <!-- 进度条区域 -->
        <el-steps :space='200'
                  :active='stepActive-0'
                  align-center
                  finish-status='success'>
          <el-step title='基本信息'></el-step>
          <el-step title='商品参数'></el-step>
          <el-step title='商品属性'></el-step>
          <el-step title='商品图片'></el-step>
          <el-step title='商品内容'></el-step>
          <el-step title='完成'></el-step>
        </el-steps>
        <!-- Tab栏区域 -->
        <el-form :model='addForm'
                 :rules='addFormRules'
                 ref='addFormRef'
                 label-position='top'
                 label-width='90px'>
          <el-tabs v-model='stepActive'
                   :before-leave='beforeTabLeave'
                   @tab-click='tabClick'
                   :tab-position='tabPosition'>
            <el-tab-pane label='基本信息' name='0'>
              <el-form-item label='商品名称' prop='goods_name'>
                <el-input v-model='addForm.goods_name'></el-input>
              </el-form-item>
              <el-form-item label='商品价格' prop='goods_price'>
                <el-input v-model='addForm.goods_price' type='number' min='0'></el-input>
              </el-form-item>
              <el-form-item label='商品重量' prop='goods_weight'>
                <el-input v-model='addForm.goods_weight' type='number' min='0'></el-input>
              </el-form-item>
              <el-form-item label='商品数量' prop='goods_number'>
                <el-input v-model='addForm.goods_number' type='number' min='0'></el-input>
              </el-form-item>
              <el-form-item label='商品分类'>
                <el-cascader
                  v-model='addForm.goods_cat'
                  :options='cateList'
                  clearable
                  :props='cateListOption'
                  @change='cateChange'></el-cascader>
              </el-form-item>
            </el-tab-pane>
            <el-tab-pane label='商品参数' name='1'>
              <el-form-item :label='item.attr_name'
                            v-for='item in paramsList'
                            class='params-form-item'
                            :key='item.attr_id'>
                <el-checkbox-group v-model='item.attr_vals' fill>
                  <el-checkbox :label='items'
                               border
                               size='mini'
                               v-for='(items,i) in item.attr_vals'
                               :key='i'></el-checkbox>
                </el-checkbox-group>
              </el-form-item>
            </el-tab-pane>
            <el-tab-pane label='商品属性' name='2'>
              <el-form-item :label='item.attr_name'
                            class='attr-form-item'
                            v-for='item in cateAttrList'
                            :key='item.attr_id'>
                <el-tag
                  :key='i'
                  v-for='(tag,i) in item.attr_vals'
                  closable
                  class='attr-tag'
                  :disable-transitions='false'
                  @close='attrTagClose(item,i)'>
                  <span>{{ tag }}</span>
                </el-tag>
                <el-input
                  class='input-new-tag'
                  v-if='item.attrVisible'
                  v-model='item.attrInputValue'
                  ref='saveTagInput'
                  size='small'
                  @keyup.enter.native='attrInputConfirm(item)'
                  @blur='attrInputConfirm(item)'>
                </el-input>
                <el-button v-else class='button-new-tag'
                           size='small'
                           @click='showInput(item)'>+ New Tag
                </el-button>
              </el-form-item>
            </el-tab-pane>
            <el-tab-pane label='商品图片' name='3'>
              <el-upload :action='uploadURL'
                         :on-remove='uploadRemove'
                         :on-preview='viewPic'
                         :on-error='uploadError'
                         :headers='uploadHeader'
                         :on-success='uploadSuccess'
                         list-type='picture'>
                <el-button size='small' type='primary'>点击上传</el-button>
              </el-upload>
              <el-dialog
                title='预览'
                :visible.sync='viewPicVisible'
                @close='closeViewPic'>
                <div class='view-image'>
                  <img :src='photoPath' alt=''>
                </div>
              </el-dialog>
            </el-tab-pane>
            <el-tab-pane label='商品内容' name='4'>
              <quill-editor v-model='addForm.goods_introduce'></quill-editor>
              <el-divider></el-divider>
              <el-button type='primary' @click='addGoods'>添加商品</el-button>
            </el-tab-pane>
          </el-tabs>
        </el-form>
      </el-row>
    </el-card>
  </div>
</template>

<script>
import _ from 'lodash'

export default {
  name: 'AddGoods',
  data() {
    return {
      // 进度条默认选中
      stepActive: '0',
      // tab栏显示位置,默认left
      tabPosition: 'left',
      // 添加商品的表单数据
      addForm: {
        goods_name: '',
        goods_price: 0,
        goods_number: 0,
        goods_weight: 0,
        // 选择的商品分类数据双向绑定
        goods_cat: [],
        // 图片上传的临时路径
        pics: [],
        // 富文本编辑器内容
        goods_introduce: '',
        // 静态属性和动态参数
        attrs: []
      },
      // 添加商品的表单验证规则
      addFormRules: {
        goods_name: [
          { required: true, message: '商品名称必填', trigger: 'blur' }
        ],
        goods_price: [
          { required: true, message: '商品价格必填', trigger: 'blur' }
        ],
        goods_number: [
          { required: true, message: '商品重量必填', trigger: 'blur' }
        ],
        goods_weight: [
          { required: true, message: '商品数量必填', trigger: 'blur' }
        ]
      },
      // 商品分类列表
      cateList: [],
      // 商品分类的级联选择框的配置对象
      cateListOption: {
        expandTrigger: 'hover',
        value: 'cat_id',
        label: 'cat_name',
        children: 'children'
      },
      // 商品参数列表
      paramsList: [],
      // 商品属性列表
      cateAttrList: [],
      // 上传图片的请求路径
      uploadURL: 'http://127.0.0.1:8888/api/private/v1/upload',
      // 图片上传配置项
      uploadHeader: {
        Authorization: window.sessionStorage.getItem('token')
      },
      // 预览图片的显示框
      viewPicVisible: false,
      // 图片预览的绝对路径
      photoPath: ''
    }
  },
  created() {
    this.getCateList()
  },
  methods: {
    // 获取商品分类数据
    async getCateList() {
      const { data: res } = await this.$http.get('categories')
      if (res.meta.status !== 200) {
        return this.$msg.error('获取商品数据失败')
      }
      this.cateList = res.data
    },
    // 商品分类级联选择框改变处理
    cateChange() {
      if (this.addForm.goods_cat.length !== 3) {
        this.addForm.goods_cat = []
      }
    },
    // 阻止Tab栏中，未填完整信息跳转
    beforeTabLeave(before, after) {
      if (after === '0' && this.addForm.goods_cat.length !== 3) {
        this.$msg.error('请选择商品分类')
        return false
      }
    },
    // Tab栏对应切换的事件处理
    async tabClick() {
      if (this.stepActive === '1') {
        // 获取参数列表
        const { data: res } = await this.$http.get(`categories/${ this.getTreeParamsId }/attributes`, {
          params: { sel: 'many' }
        })
        if (res.meta.status !== 200) {
          return this.$msg.error('获取参数列表失败')
        }
        // 将参数信息处理为数组
        res.data.forEach(item => {
          item.attr_vals = item.attr_vals.length === 0 ? item.attr_vals : item.attr_vals.split(',')
        })
        this.paramsList = res.data
      } else if (this.stepActive === '2') {
        // 获取属性列表
        const { data: res } = await this.$http.get(`categories/${ this.getTreeParamsId }/attributes`, {
          params: { sel: 'only' }
        })
        if (res.meta.status !== 200) {
          return this.$msg.error('获取参数列表失败')
        }
        res.data.forEach(item => {
          item.attr_vals = item.attr_vals.length > 0 ? item.attr_vals.split(',') : []
          item.attrVisible = false
          item.attrInputValue = ''
        })
        this.cateAttrList = res.data
      }
    },
    // Tab栏中静态属性的tag标签关闭事件
    async attrTagClose(row, i) {
      const res = await this.$confirm('你确定删除该属性嘛?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).catch(err => err)
      if (res !== 'confirm') return
      row.attr_vals.splice(i, 1)
      this.updateAttrTags(row, '删除成功')
    },
    // tag标签静态属性新生成标签的input触发事件
    attrInputConfirm(row) {
      console.log(row)
      if (row.attrInputValue.trim().length === 0) {
        row.attrVisible = false
        this.attrInputValue = ''
        return
      }
      row.attr_vals.push(row.attrInputValue)
      row.attrVisible = false
      row.attrInputValue = ''
      this.updateAttrTags(row, '添加成功')
    },
    // 发起请求更新标签参数
    async updateAttrTags(row, msg) {
      const { data: res } = await this.$http.put(`categories/${ this.getTreeParamsId }/attributes/${ row.attr_id }`, {
        attr_name: row.attr_name,
        attr_sel: row.attr_sel,
        attr_vals: row.attr_vals.join(',')
      })
      if (res.meta.status !== 200) {
        return this.$msg.error(res.meta.msg)
      }
      this.$msg.success(msg)
    },
    // 生成静态属性的tag标签的input和button切换
    showInput(item) {
      item.attrVisible = true
      this.$nextTick(() => {
        this.$refs.saveTagInput.forEach(item => {
          item.$refs.input.focus()
        })
      })
    },
    // 上传图片失败
    uploadError(err) {
      this.$msg.error(err)
    },
    // 移除需要上传的图片的事件
    uploadRemove(file) {
      const picPath = file.response.data.tmp_path
      const index = this.addForm.pics.findIndex(i => i.pic === picPath)
      this.addForm.pics.splice(index, 1)
      this.$msg.success('删除成功')
    },
    // 图片上传成功的回调
    uploadSuccess(res) {
      const picObj = {}
      picObj.pic = res.data.tmp_path
      this.addForm.pics.push(picObj)
      this.$msg.success('上传成功')
    },
    // 点击已经上传成功的图片事件
    viewPic(file) {
      this.photoPath = file.response.data.url
      this.viewPicVisible = true
    },
    // 点击关闭图片预览框
    closeViewPic() {
      this.viewPicVisible = false
    },
    // 确定添加商品
    addGoods() {
      this.$refs.addFormRef.validate(async valid => {
        if (!valid) {
          this.stepActive = '0'
          return this.$msg.error('表单还未填写完整')
        }
        // 将商品参数处理为字符串
        const formClone = _.cloneDeep(this.addForm)
        formClone.goods_cat = formClone.goods_cat.join(',')
        // 将动态参数和静态属性添加到提交表单中
        // 动态参数
        this.paramsList.forEach(item => {
          const list = {
            attr_id: item.attr_id,
            attr_value: item.attr_vals.join(',')
          }
          this.addForm.attrs.push(list)
        })
        // 静态属性
        this.cateAttrList.forEach(item => {
          const list = {
            attr_id: item.attr_id,
            attr_value: item.attr_vals.join(',')
          }
          this.addForm.attrs.push(list)
        })
        // 将属性和参数push到将要提交的formClone中
        formClone.attrs = this.addForm.attrs
        // 提交form表单
        const { data: res } = await this.$http.post('goods', formClone)
        if (res.meta.status !== 201) {
          return this.$msg.error('添加商品失败')
        }
        this.$msg.success('添加商品成功')
        this.$router.push('/goods')
      })
    }
  },
  computed: {
    // 获取三级参数的列表
    getTreeParamsId() {
      if (this.addForm.goods_cat.length === 3) {
        return this.addForm.goods_cat[2]
      }
      return null
    }
  }
}
</script>

<style lang='less' scoped>
.row-step {
  margin: 15px 0;

  .el-steps {
    margin-bottom: 15px;
  }
}

.params-form-item {
  border-bottom: 1px solid #999999;

  .el-checkbox {
    margin: 0 5px 0 0;
    box-shadow: 0 0 5px #e3e3e3;
  }
}

.el-input {
  width: 60%;
}

.attr-tag {
  margin-right: 5px;
}

.attr-form-item {
  border-top: 1px dashed #a6dffd;
}

.view-image {
  width: 100%;
  height: 300px;

  img {
    width: 100%;
    height: 100%;
  }
}
</style>
